---
title: DeepBookV3 SDK
---

The DeepBook typescript SDK abstracts away the transaction calls, allowing for direct interactions with the DeepBook package. 

- [SDK Repository](https://github.com/MystenLabs/sui/tree/main/sdk/deepbook-v3)
- [NPM version](https://www.npmjs.com/package/@mysten/deepbook-v3)

## Install

To use the SDK in your projects, install the `@mysten/deepbook` package.

```sh npm2yarn
npm install @mysten/deepbook-v3
```

## Constants

The DeepBookV3 SDK includes a constants file (`/utils/constants.ts`) that maintains the latest deployed addresses for DeepBook, as well as a few staple coins and pools. 

<details>
<summary>
`constants.ts`
</summary>
{@inject: sdk/deepbook/src/utils/constants.ts}
</details>

## DeepBookClient

To work with DeepBook, you must create a `DeepBookClient`. To construct the `DeepBookClient`, pass in a `SuiClient`, the sender address, and environment. The [Sui TypeScript SDK](https://sdk.mystenlabs.com/typescript) provides the `SuiClient` and key functionality necessary to process transactions. The following example imports those libraries, as well. 

```tsx
import { SuiClient, getFullnodeUrl } from "@mysten/sui/client";
import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519";
import { decodeSuiPrivateKey } from "@mysten/sui/cryptography";

import { DeepBookClient } from "@mysten/deepbook-v3";

class DeepBookMarketMaker {
    dbClient: DeepBookClient; // For building transactions
    suiClient: SuiClient; // For executing transactions
    keypair: Ed25519Keypair; // For signing transactions

    constructor(privateKey: string, env: 'testnet' | 'mainnet') {
        this.keypair = this.getSignerFromPK(privateKey);
        this.suiClient = new SuiClient({
            url: getFullnodeUrl(env)
        })
        this.dbClient = new DeepBookClient({
            address: this.getActiveAddress(),
            env: env,
            client: this.suiClient,
        });
    }

    getSignerFromPK = (privateKey: string): Ed25519Keypair => {
      const { schema, secretKey } = decodeSuiPrivateKey(privateKey);
      if (schema === 'ED25519') return Ed25519Keypair.fromSecretKey(secretKey);
  
      throw new Error(`Unsupported schema: ${schema}`);
    };

    getActiveAddress() {
        return this.keypair.toSuiAddress();
    }
}
```

## Keys: Coin, Pool, and Manager {#keys}

Functions that require the input of a coin, pool, or a manager require the key of any such object as the parameter. The SDK manages a key:value relationship of this data in memory. Some default data comes with the SDK (as seen in `utils/constants.ts`). Coins are stored in a `CoinMap` and pools in a `PoolMap` in the config.

### Balance manager

Before placing any trade, you must supply a balance manager address to the client. The manager key points to an object defined by the `BalanceManager` interface in the client. [BalanceManager docs](./deepbookv3/balance-manager.mdx). Initialize the balance manager with the client. If you don't create a balance manager, you can rely on the client to create one, but then the user must reinitialize the client.

Example using an existing balance manager:
    
```tsx
import { SuiClient, getFullnodeUrl } from "@mysten/sui/client";
import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519";
import { decodeSuiPrivateKey } from "@mysten/sui/cryptography";
import { config } from 'dotenv';
config();

import { DeepBookClient } from "../src";
import { BalanceManager } from "./types";

// Used wherever balance manager key is required
const BALANCE_MANAGER_KEY = 'MANAGER_1';

class DeepBookMarketMaker {
    dbClient: DeepBookClient; // For building transactions
    suiClient: SuiClient; // For executing transactions
    keypair: Ed25519Keypair; // For signing transactions
    env: 'testnet' | 'mainnet';

    constructor(privateKey: string, env: 'testnet' | 'mainnet') {
        this.env = env;
        this.keypair = this.getSignerFromPK(privateKey);
        this.suiClient = new SuiClient({
            url: getFullnodeUrl(env)
        })
        this.dbClient = new DeepBookClient({
            address: this.getActiveAddress(),
            env: env,
            client: this.suiClient,
            balanceManagers: this.getBalanceManagers()
        });
    }

    getSignerFromPK = (privateKey: string): Ed25519Keypair => {
    const { schema, secretKey } = decodeSuiPrivateKey(privateKey);
    if (schema === 'ED25519') return Ed25519Keypair.fromSecretKey(secretKey);

    throw new Error(`Unsupported schema: ${schema}`);
  };

    getActiveAddress() {
        return this.keypair.toSuiAddress();
    }

    getBalanceManagers(): { [key: string]: BalanceManager } {
        // Used wherever balance manager key is required
        const balanceManagerAddress = process.env.BALANCE_MANAGER_ADDRESS;
        const balanceManagerTradeCap = process.env.BALANCE_MANAGER_TRADE_CAP;
        if (!balanceManagerAddress) {
            throw new Error('No balance manager address found');
        }
        return {
            [BALANCE_MANAGER_KEY]: {
                address: balanceManagerAddress,
                tradeCap: balanceManagerTradeCap
            }
        }
    }
}
```
    
Example creating a balance manager:
    
```tsx
import { SuiClient, getFullnodeUrl } from "@mysten/sui/client";
import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519";
import { decodeSuiPrivateKey } from "@mysten/sui/cryptography";

import { DeepBookClient } from "../src";
import { Transaction } from "@mysten/sui/transactions";
import { BalanceManager } from "./types";

// Used wherever balance manager key is required
const BALANCE_MANAGER_KEY = 'MANAGER_1';

class DeepBookMarketMaker {
    dbClient: DeepBookClient; // For building transactions
    suiClient: SuiClient; // For executing transactions
    keypair: Ed25519Keypair; // For signing transactions
    env: 'testnet' | 'mainnet';

    constructor(privateKey: string, env: 'testnet' | 'mainnet') {
        this.env = env;
        this.keypair = this.getSignerFromPK(privateKey);
        this.suiClient = new SuiClient({
            url: getFullnodeUrl(env)
        })
        this.dbClient = new DeepBookClient({
            address: this.getActiveAddress(),
            env: env,
            client: this.suiClient,
        });
    }

    getSignerFromPK = (privateKey: string): Ed25519Keypair => {
      const { schema, secretKey } = decodeSuiPrivateKey(privateKey);
      if (schema === 'ED25519') return Ed25519Keypair.fromSecretKey(secretKey);
  
      throw new Error(`Unsupported schema: ${schema}`);
    };

    getActiveAddress() {
        return this.keypair.toSuiAddress();
    }

    async createBalanceManagerAndReinitialize() {
        let tx = new Transaction();
        tx.add(this.dbClient.balanceManager.createAndShareBalanceManager());
        
        const res = await this.suiClient.signAndExecuteTransaction({
            transaction: tx,
            signer: this.keypair,
            options: {
                showEffects: true,
                showObjectChanges: true,
            },
        })

        // @ts-ignore
        const balanceManagerAddress = res.objectChanges?.find((change) => {
            return change.type === 'created' && change.objectType.includes('BalanceManager');
        })?.['objectId'];

        const balanceManagers: { [key: string]: BalanceManager } = {
            [BALANCE_MANAGER_KEY]: {
                address: balanceManagerAddress,
                tradeCap: undefined,
            }
        }

        this.dbClient = new DeepBookClient({
            address: this.getActiveAddress(),
            env: this.env,
            client: this.suiClient,
            balanceManagers: balanceManagers,
        })
    }
}
```

### Coin

The SDK comes with four default coins on Testnet and five default coins on Mainnet. 

**Default Testnet coins**
- DEEP
- SUI
- DBUSDC
- DBUSDT

**Default Mainnet coins**
- DEEP
- SUI
- USDC
- USDT
- WETH

You can also initialize the SDK with custom coins to interact with pools that are not supported by default. To do this, create a `CoinMap` object and pass it to the constructor of the client.

### Pool

Similar to coins, the SDK comes with default pools. You can provide a `PoolMap` during construction to override this behavior.
    
```tsx
import { decodeSuiPrivateKey } from '@mysten/sui.js/cryptography';
import { getFullnodeUrl, SuiClient } from '@mysten/sui/client';
import type { Keypair } from '@mysten/sui/cryptography';
import { Ed25519Keypair } from '@mysten/sui/keypairs/ed25519';
import type { Transaction } from '@mysten/sui/transactions';

import { DeepBookClient } from '../src/index.js'; // Adjust path according to new structure
import type { BalanceManager } from '../src/types/index.js';

export class DeepBookMarketMaker extends DeepBookClient {
  keypair: Keypair;
  suiClient: SuiClient;

  constructor(
    keypair: string | Keypair,
    env: 'testnet' | 'mainnet',
    balanceManagers?: { [key: string]: BalanceManager },
    adminCap?: string,
  ) {
    let resolvedKeypair: Keypair;

    if (typeof keypair === 'string') {
      resolvedKeypair = DeepBookMarketMaker.#getSignerFromPK(keypair);
    } else {
      resolvedKeypair = keypair;
    }

    const address = resolvedKeypair.toSuiAddress();

    super({
      address: address,
      env: env,
      client: new SuiClient({
        url: getFullnodeUrl(env),
      }),
      balanceManagers: balanceManagers,
      adminCap: adminCap,
    });

    this.keypair = resolvedKeypair;
    this.suiClient = new SuiClient({
      url: getFullnodeUrl(env),
    });
  }

  static #getSignerFromPK = (privateKey: string) => {
    const { schema, secretKey } = decodeSuiPrivateKey(privateKey);
    if (schema === 'ED25519') return Ed25519Keypair.fromSecretKey(secretKey);

    throw new Error(`Unsupported schema: ${schema}`);
  };

  signAndExecute = async (tx: Transaction) => {
    // remove arguments
    return this.suiClient.signAndExecuteTransaction({
      transaction: tx,
      signer: this.keypair,
      options: {
        showEffects: true,
        showObjectChanges: true,
      },
    });
  };

  getActiveAddress() {
    return this.keypair.getPublicKey().toSuiAddress();
  }
}

```

### Example setup

The following example uses the default pools and coins provided.
    
```tsx
import { Transaction } from '@mysten/sui/transactions';
import { DeepBookMarketMaker } from './deepbookMarketMaker.js';

(async () => {
  const privateKey = ''; // Can encapsalate this in a .env file

  // Initialize with balance managers if created
  const balanceManagers = {
    MANAGER_1: {
      address: '',
      tradeCap: '',
    },
  };
  const mmClient = new DeepBookMarketMaker(
    privateKey,
    'testnet',
    balanceManagers,
  );

  const tx = new Transaction();

  // Read only call
  console.log(await mmClient.checkManagerBalance('MANAGER_1', 'SUI'));
  console.log(await mmClient.getLevel2Range('SUI_DBUSDC', 0.1, 100, true));

  // Balance manager contract call
  mmClient.balanceManager.depositIntoManager('MANAGER_1', 'DBUSDT', 10000)(tx);
  mmClient.balanceManager.withdrawAllFromManager(
    'MANAGER_1',
    'DBUSDT',
    mmClient.getActiveAddress(),
  )(tx);

  // Example custom PTB call in DeepBookMarketMaker class
  mmClient.placeLimitOrderExample(tx);
  mmClient.flashLoanExample(tx);

  let res = await mmClient.signAndExecute(tx);

  console.dir(res, { depth: null });
})();

```
